package com.xydtech.busiflw.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xydtech.busiflw.service.IBusinessFlowLogicService;
import com.xydtech.common.constant.Constants;
import com.xydtech.common.constant.FlowConstants;
import com.xydtech.common.core.domain.AjaxResult;
import com.xydtech.common.core.domain.entity.SysUser;
import com.xydtech.workflow.domain.WflSteplogic;
import com.xydtech.workflow.mapper.WflSteplogicMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 创建时间：2022/1/10 10:37
 * 项目名称：xydtech
 * @author JHON
 * @version 1.0
 * @since JDK 1.8.0_201
 * 文件名称：BusinessFlowLogicServiceImpl
 * 类说明：业务流程逻辑Service

 */
@Service
public class BusinessFlowLogicServiceImpl implements IBusinessFlowLogicService {
    @Autowired
    private WflSteplogicMapper wflSteplogicMapper;

    /**
     * 执行流程节点逻辑单元
     * @Title: flowLogicRunning
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param keyInfo
     * @param approveType
     * @param currentUser
     * @return com.xydtech.common.core.domain.AjaxResult
     * @exception
     * @author JHON
     * @Date 2022/1/10 10:36
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult flowLogicRunning(Long versionId, String instanceId, Long stepId, String keyInfo, String approveType, SysUser currentUser) {
        WflSteplogic wflSteplogic = new WflSteplogic();
        wflSteplogic.setVersionId(versionId);
        wflSteplogic.setStepId(stepId);
        //查询流程节点配置的逻辑单元
        List<WflSteplogic> stepLogicList = wflSteplogicMapper.selectWflSteplogicList(wflSteplogic);
        if (stepLogicList.size() > 0) {
            for (WflSteplogic stepLogic : stepLogicList) {
                AjaxResult ajaxResult = new AjaxResult();
                if (FlowConstants.LOGIC_RUN_STS_1.equals(stepLogic.getRunSts())) {
                    /** 执行时点1-始终执行*/
                    ajaxResult = runLogic(versionId, instanceId, stepId, keyInfo, stepLogic, currentUser);
                } else if (FlowConstants.LOGIC_RUN_STS_2.equals(stepLogic.getRunSts()) && FlowConstants.APPROVE_TYPE_T.equals(approveType)) {
                    /** 执行时点2-同意时执行*/
                    ajaxResult = runLogic(versionId, instanceId, stepId, keyInfo, stepLogic, currentUser);
                } else if (FlowConstants.LOGIC_RUN_STS_3.equals(stepLogic.getRunSts()) && approveType.startsWith(FlowConstants.APPROVE_TYPE_R)) {
                    /** 执行时点3-退回时执行*/
                    ajaxResult = runLogic(versionId, instanceId, stepId, keyInfo, stepLogic, currentUser);
                } else if (FlowConstants.LOGIC_RUN_STS_4.equals(stepLogic.getRunSts()) && FlowConstants.APPROVE_TYPE_F.equals(approveType)) {
                    /** 执行时点4-拒绝时执行 */
                    ajaxResult = runLogic(versionId, instanceId, stepId, keyInfo, stepLogic, currentUser);
                }
                String code = ajaxResult.get(AjaxResult.CODE_TAG) == null ? "0" : ajaxResult.get(Constants.CODE).toString();
                if (!Constants.SUCCESS.equals(code)) {
                    return AjaxResult.error(ajaxResult.get(AjaxResult.MSG_TAG).toString());
                }
            }
            return AjaxResult.success();
        }
        return AjaxResult.success();
    }

    /**
     *运行逻辑单元
     * @Title: runLogic
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param keyInfo
     * @param stepLogic
     * @param currentUser
     * @return com.xydtech.common.core.domain.AjaxResult
     * @exception
     * @author JHON
     * @Date 2022/1/10 14:23
     **/
    public AjaxResult runLogic(Long versionId, String instanceId, Long stepId, String keyInfo, WflSteplogic stepLogic, SysUser currentUser) {
        if (FlowConstants.LOGIC_TYPE_STRATEGY.equals(stepLogic.getLogicType())) {
            return runStrategyLogic(versionId, instanceId, Long.valueOf(stepLogic.getRiskStrategy()), keyInfo, currentUser);
        } else if (FlowConstants.LOGIC_TYPE_CLASS.equals(stepLogic.getLogicType())) {
            return runClassLogic(versionId, instanceId, stepId, keyInfo, stepLogic);
        }
        return AjaxResult.success();
    }

    /**
     * 运行策略组逻辑单元
     * @Title: runStrategyLogic
     * @param versionId
     * @param instanceId
     * @param groupId
     * @param keyInfo
     * @return com.xydtech.common.core.domain.AjaxResult
     * @exception
     * @author JHON
     * @Date 2022/1/10 13:33
     **/
    public AjaxResult runStrategyLogic(Long versionId, String instanceId, Long groupId, String keyInfo, SysUser currentUser) {
        JSONObject keyInfoObject = JSONObject.parseObject(keyInfo);
        String name = keyInfoObject.getString("cname");
        String idCardNumber = keyInfoObject.getString("cardNum");
        String phoneNumbers = keyInfoObject.getString("phoneNum");
        try {
            //riskEngineRunService.strategyGroupRun(instanceId, name, idCardNumber, phoneNumbers, groupId, currentUser.getDeptId(), currentUser.getUserId());
            return AjaxResult.success();
        } catch (Exception e) {
            String msg = e.getMessage() == null ? e.getCause().getMessage() : e.getMessage();
            return AjaxResult.error(msg);
        }

    }

    /**
     *运行外部类逻辑单元
     * @Title: runClassLogic
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param keyInfo
     * @return com.xydtech.common.core.domain.AjaxResult
     * @exception
     * @author JHON
     * @Date 2022/1/10 13:33
     **/
    public AjaxResult runClassLogic(Long versionId, String instanceId, Long stepId, String keyInfo, WflSteplogic stepLogic) {

        Class<?> clazz;
        try {
            clazz = Class.forName(stepLogic.getClassName());
            Object classObj = clazz.newInstance();
            /* 通过上面得到的类定义对象clazz得到指定名称和参数类型列表的方法定义 */
            Method m = clazz.getMethod(stepLogic.getMethodName(), Map.class);
            /** 在指定的对象上调用符合上面方法定义的方法， 并且制定方法的入口参数值列表*/
            HashMap map = JSON.parseObject(keyInfo, HashMap.class);
            map.put("instanceId", instanceId);
            m.invoke(classObj, map);
        } catch (Exception e) {
            String msg = e.getMessage() == null ? e.getCause().getMessage() : e.getMessage();
            return AjaxResult.error("调用逻辑单元出错：" + msg);
        }
        return AjaxResult.success();
    }
}